﻿using System;
using System.Collections;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Linq;
using System.Collections.Generic;

using Emc.Documentum.FS.Services.Core;
using Emc.Documentum.FS.DataModel.Core;
using Emc.Documentum.FS.DataModel.Core.Query;
using Emc.Documentum.FS.DataModel.Core.Properties;
using Emc.Documentum.FS.DataModel.Core.Profiles;
using Emc.Documentum.FS.Runtime;
using Emc.Documentum.FS.Runtime.Context;
using Emc.Documentum.FS.DataModel.Core.Context;
using Emc.Documentum.FS.DataModel.Core.Content;
using Emc.Documentum.FS.Services.Bpm;
using Emc.Documentum.FS.DataModel.Core.Bpm;
using System.Xml;


namespace MonsterMashUpload
{
    public partial class _Default : System.Web.UI.Page
    {

        private string defaultRepository = null;
        private string secondaryRepository = null;
        private string userName = null;
        private string password = null;
        private IServiceContext serviceContext;
        private IObjectService objectService;
        private IQueryService queryService;
        private IWorkflowService workflowService;

        private void initializeContext()
        {
            //grab values from associated config file:
            defaultRepository = ConfigurationManager.AppSettings["Repository"];
            secondaryRepository = ConfigurationManager.AppSettings["Repository"];
            userName = ConfigurationManager.AppSettings["DctmUser"];
            password = ConfigurationManager.AppSettings["DctmPassword"];

            ContextFactory contextFactory = ContextFactory.Instance;
            serviceContext = contextFactory.NewContext();

            RepositoryIdentity repoId = new RepositoryIdentity();
            RepositoryIdentity repositoryIdentity =
                new RepositoryIdentity(defaultRepository, userName, password, "");
            serviceContext.AddIdentity(repositoryIdentity);

            ContentTransferProfile contentTransferProfile = new ContentTransferProfile();
            contentTransferProfile.TransferMode = ContentTransferMode.MTOM;
            contentTransferProfile.Geolocation = "Toronto";
            serviceContext.SetProfile(contentTransferProfile);

            if (!String.IsNullOrEmpty(secondaryRepository))
            {
                RepositoryIdentity repoId1 = new RepositoryIdentity();
                repoId1.RepositoryName = secondaryRepository;
                repoId1.UserName = userName;
                repoId1.Password = password;
                serviceContext.AddIdentity(repoId1);
            }
        }


        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void m_UploadButton_Click(object sender, EventArgs e)
        {
            String registryUsername = m_UploaderUsername.Text;
            String registryPassword = m_UploaderPassword.Text;
            Byte[] modelBytes = m_ModelToUpload.FileBytes;
            Byte[] texture1Bytes = m_Texture1Upload.FileBytes;
            Byte[] texture2Bytes = m_Texture2Upload.FileBytes;
            Byte[] texture3Bytes = m_Texture3Upload.FileBytes;
            int countOfTextures = 0;
            String textureName1 = null;
            String textureName2 = null;
            String textureName3 = null;

            initializeContext();

            ServiceFactory serviceFactory = ServiceFactory.Instance;
            objectService = serviceFactory.GetRemoteService<IObjectService>(serviceContext);
            workflowService = serviceFactory.GetRemoteService<IWorkflowService>(serviceContext);

            try
            {
                ObjectIdentitySet objIdSet = new ObjectIdentitySet();
                ObjectIdentity objId = new ObjectIdentity();
                objId.RepositoryName = defaultRepository;
                objId.ValueType = ObjectIdentityType.OBJECT_PATH;

                OperationOptions ops = new OperationOptions();
                DataPackage newTextures = new DataPackage();
                newTextures.RepositoryName = defaultRepository;
                DataObject texture1 = new DataObject();
                ObjectIdentity texture1Id = new ObjectIdentity(defaultRepository);
                texture1.Identity = texture1Id;
                textureName1 = m_Texture1Upload.FileName;
                texture1.Properties.Set<String>("object_name", textureName1);
                texture1.Type = "dl_model";
                Emc.Documentum.FS.DataModel.Core.Content.Content texture1Content = null;
                if (null != texture1Bytes && texture1Bytes.Count() > 0)
                {
                    texture1Content = new BinaryContent(texture1Bytes, String.Empty);
                    texture1.Contents.Add(texture1Content);
                    ops.PropertyProfile.FilterMode = PropertyFilterMode.SPECIFIED_BY_EXCLUDE;
                    newTextures.AddDataObject(texture1);
                    texture1.Properties.Set<String>("v_uploader", registryUsername);
                    texture1.Properties.Set<String>("v_uploader_password", registryPassword);
                    countOfTextures++;
                }
                DataObject texture2 = new DataObject();
                ObjectIdentity texture2Id = new ObjectIdentity(defaultRepository);
                texture2.Identity = texture2Id;
                textureName2 = m_Texture2Upload.FileName;
                texture2.Properties.Set<String>("object_name", textureName2);
                texture2.Type = "dl_model";
                Emc.Documentum.FS.DataModel.Core.Content.Content texture2Content = null;
                if (null != texture2Bytes && texture2Bytes.Count() > 0)
                {
                    texture2Content = new BinaryContent(texture2Bytes, String.Empty);
                    texture2.Contents.Add(texture2Content);
                    ops.PropertyProfile.FilterMode = PropertyFilterMode.SPECIFIED_BY_EXCLUDE;
                    newTextures.AddDataObject(texture2);
                    texture2.Properties.Set<String>("v_uploader", registryUsername);
                    texture2.Properties.Set<String>("v_uploader_password", registryPassword);
                    countOfTextures++;
                }
                DataObject texture3 = new DataObject();
                ObjectIdentity texture3Id = new ObjectIdentity(defaultRepository);
                texture3.Identity = texture3Id;
                textureName3 = m_Texture3Upload.FileName;
                texture3.Properties.Set<String>("object_name", textureName3);
                texture3.Type = "dl_model";
                Emc.Documentum.FS.DataModel.Core.Content.Content texture3Content = null;
                if (null != texture3Bytes && texture3Bytes.Count() > 0)
                {
                    texture3Content = new BinaryContent(texture3Bytes, String.Empty);
                    texture3.Contents.Add(texture3Content);
                    ops.PropertyProfile.FilterMode = PropertyFilterMode.SPECIFIED_BY_EXCLUDE;
                    newTextures.AddDataObject(texture3);
                    texture3.Properties.Set<String>("v_uploader", registryUsername);
                    texture3.Properties.Set<String>("v_uploader_password", registryPassword);
                    countOfTextures++;
                }

                DataPackage returnedTextures = null;

                if (countOfTextures > 0)
                {
                    returnedTextures = objectService.Create(newTextures, ops);
                }

                DataPackage newObjects = new DataPackage();
                newObjects.RepositoryName = defaultRepository;
                DataObject newModel = new DataObject();

                ObjectIdentity newObjId = new ObjectIdentity(defaultRepository);
                newModel.Identity = newObjId;
                newModel.Type = "dl_model";
                newModel.Properties.Set<String>("object_name", m_ModelToUpload.FileName);
                newModel.Properties.Set<String>("v_uploader", registryUsername);
                newModel.Properties.Set<String>("v_uploader_password", registryPassword);
                String[] modelTextures = new String[countOfTextures];

                if (null != returnedTextures && null != returnedTextures.DataObjects)
                {
                    if (returnedTextures.DataObjects.Count > 0)
                    {
                        texture1Id = returnedTextures.DataObjects[0].Identity;
                        modelTextures[0] = texture1Id.GetValueAsString();
                    }
                    if (returnedTextures.DataObjects.Count > 1)
                    {
                        texture2Id = returnedTextures.DataObjects[1].Identity;
                        modelTextures[1] = texture2Id.GetValueAsString();
                    }
                    if (returnedTextures.DataObjects.Count > 2)
                    {
                        texture3Id = returnedTextures.DataObjects[2].Identity;
                        modelTextures[2] = texture3Id.GetValueAsString();
                    }

                    newModel.Properties.Set<String[]>("v_textures", modelTextures);

                }

                Emc.Documentum.FS.DataModel.Core.Content.Content modelContent = null;
                if (null != modelBytes)
                {
                    modelContent = new BinaryContent(modelBytes, String.Empty);
                    newModel.Contents.Add(modelContent);
                
                    ops.PropertyProfile.FilterMode = PropertyFilterMode.SPECIFIED_BY_EXCLUDE;

                    newObjects.AddDataObject(newModel);

                    DataPackage returnedPackage = objectService.Create(newObjects, ops);

                    DataPackage processTemplates = workflowService.GetProcessTemplates(defaultRepository, "/damadmin/ModelWorkflow4", null);
                    DataObject modelWorkflowTemplate = processTemplates.DataObjects[0];
                    ObjectIdentity modelWorkflowId = modelWorkflowTemplate.Identity;
                    Emc.Documentum.FS.DataModel.Core.Bpm.ProcessInfo modelWorkflowInfo = workflowService.GetProcessInfo(modelWorkflowId);

                    ObjectIdentity modelId = returnedPackage.DataObjects[0].Identity;
                    ObjectId modelRObjectId = new ObjectId(modelId.GetValueAsString());
                    //modelWorkflowInfo.AddWorkflowAttachment("Package0", modelRObjectId);
                    ProcessPackageInfo package0 = new ProcessPackageInfo();
                    package0.PackageName = "Package0";
                    List<ObjectId> packageContents = new List<ObjectId>();
                    packageContents.Add(modelRObjectId);

                    foreach (String textureRObjId in modelTextures)
                    {
                        ObjectId textureObjId = new ObjectId(textureRObjId);
                        modelWorkflowInfo.AddWorkflowAttachment(null, textureObjId);
                    }

                    package0.AddDocuments(packageContents);
                    modelWorkflowInfo.Packages.Add(package0);
                    
                    ObjectIdentity processId = workflowService.StartProcess(modelWorkflowInfo);
                
                }

                String registryName = ConfigurationManager.AppSettings["MonsterMashRegistry"];
                xDB_SOAP.XhiveServerSessionIfClient client = new MonsterMashUpload.xDB_SOAP.XhiveServerSessionIfClient();

                String sessionID = client.connect(registryUsername, registryPassword, registryName);
                String strXml = null;

                try
                {
                    strXml = client.getDocument(sessionID, "/" + registryUsername + "/links.xml", null, null);
                }
                catch (Exception ex)
                {
                    String err = ex.ToString();
                }

                XmlDocument doc = new XmlDocument();
                XmlElement topNode = null;
                XmlElement rootNode = null;

                if (!String.IsNullOrEmpty(strXml))
                {
                    doc.LoadXml(strXml);
                    rootNode = doc.DocumentElement;
                    XmlNodeList nodes = doc.GetElementsByTagName("GameContent");
                    if (null == nodes || nodes.Count == 0)
                    {
                        topNode = doc.CreateElement("GameContent");
                    }
                    else
                    {
                        topNode = (XmlElement)nodes[0];
                        rootNode.RemoveChild(topNode);
                    }
                    client.checkOutDocument(sessionID, registryUsername + "/links.xml", null);
                }
                else
                {
                    rootNode = doc.CreateElement("MonsterMash2010");
                    topNode = doc.CreateElement("GameContent");
                }

                XmlElement modelToAdd = doc.CreateElement("Model");
                XmlAttribute modelNameAttribute = doc.CreateAttribute("Name");
                modelNameAttribute.Value = m_ModelToUpload.FileName;
                modelToAdd.Attributes.Append(modelNameAttribute);
                XmlElement textureNode1 = doc.CreateElement("Texture");
                XmlElement textureNode2 = doc.CreateElement("Texture");
                XmlElement textureNode3 = doc.CreateElement("Texture");

                if (null != returnedTextures && null != returnedTextures.DataObjects)
                {
                    if (returnedTextures.DataObjects.Count > 0)
                    {
                        textureNode1.InnerText = textureName1;
                        modelToAdd.AppendChild(textureNode1);
                    }
                    if (returnedTextures.DataObjects.Count > 1)
                    {
                        textureNode2.InnerText = textureName2;
                        modelToAdd.AppendChild(textureNode2);
                    }
                    if (returnedTextures.DataObjects.Count > 2)
                    {
                        textureNode3.InnerText = textureName3;
                        modelToAdd.AppendChild(textureNode3);
                    }
                }

                topNode.AppendChild(modelToAdd);

                if (!String.IsNullOrEmpty(strXml))
                {
                    doc.DocumentElement.AppendChild(topNode);
                }
                else
                {
                    rootNode.AppendChild(topNode);
                    doc.AppendChild(rootNode);
                }

                if (!String.IsNullOrEmpty(strXml))
                {
                    client.checkInDocument(sessionID, registryUsername + "/links.xml", null, String.Empty, null, doc.OuterXml);
                }
                else
                {
                    try
                    {
                        client.storeDocument(sessionID, registryUsername + "/links.xml", false, null, doc.OuterXml);
                    }
                    catch (Exception ex2)
                    {
                        String errMsg = ex2.ToString();
                    }
                }


            }
            catch (Exception ex)
            {
                String str = ex.ToString();
            }

            
        }
    }
}
